package com.why.simpleboot.core.core.aop.proxy;

import com.why.simpleboot.core.common.utils.SimpleReflectUtils;
import com.why.simpleboot.core.core.aop.entity.MethodInvocation;
import com.why.simpleboot.core.core.aop.interceptor.Interceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @program: why-simpleboot-framework
 * @description:
 * @author: @why
 * @create: 2021-05-26 21:40
 **/
public class JdkProxy implements InvocationHandler {
    private static final Logger logger = LoggerFactory.getLogger(JdkProxy.class);

    private Object target;
    private Interceptor interceptor;

    public JdkProxy(Object target, Interceptor interceptor) {
        this.target = target;
        this.interceptor = interceptor;
    }

    /**
     * 将原始的bean进行包装
     *
     * @param srcObject
     * @param interceptor
     * @return
     */
    public static Object wrapperBean(Object srcObject, Interceptor interceptor) {
        JdkProxy proxy = new JdkProxy(srcObject, interceptor);

        Object proxyInstance = Proxy.newProxyInstance(srcObject.getClass().getClassLoader(),
                srcObject.getClass().getInterfaces(),
                proxy);

        logger.info("create jdk porxy:{}", proxyInstance);
        return proxyInstance;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        if (!NoProxyMethodName.NO_PROXY_METHODS.contains(method.getName())) {
            MethodInvocation invocation = new MethodInvocation(method, target, args);
            return interceptor.proceed(invocation);
        } else {
            return SimpleReflectUtils.invokeMethod(target, method, args);
        }


    }
}
